#include <iostream>
#include <map>
#include <unordered_map>

/*
 存储时是根据key的hash值判断元素是否相同，即unordered_map内部元素是无序的，
 而map中的元素是按照二叉搜索树存储（用红黑树实现），进行中序遍历会得到有序遍历。
 ** 所以使用时map的key需要定义operator<。
 ** 而unordered_map需要定义hash_value函数并且重载operator==。
 但是很多系统内置的数据类型都自带这些

 中序遍历： 左根右
 前序(根左右)，中序(左根右)，后序(左右根) 
 是根据根的位置确定的前中后
*/

struct CityRecord
{
    std::string Name;
    uint64_t Population;
    double Latitude,Longieude;

    //map 自定义数据作为key，需要实现比较函数 less 
    bool operator<(const CityRecord& other) const 
    {
        return Population < other.Population;
    }

    // bool operator=(const CityRecord& other)
    // {
    //       return (Name == other.Name && Population == other.Population && Latitude == other.Latitude && Longieude == other.Longieude);
    // }
};

namespace std {
    template<>
    struct hash<CityRecord>
    {
       size_t operator()(const CityRecord& key)
       {
          return hash<std::string>{}(key.Name); //hash<std::string>()(key.Name)
        //   using boost::hash_value;
        //   using boost::hash_combine;
        //   std::size_t seed = 0;

        // // Modify 'seed' by XORing and bit-shifting in
        // // one member of 'Key' after the other:
        //  hash_combine(seed,hash_value(key.Name));
        //  hash_combine(seed,hash_value(key.Population)); 
       }

    };
    
}
int main()
{

     //std::unordered_map<CityRecord, uint32_t> foundedMap;
    // foundedMap[CityRecord{ "beijing", 5000000, 2.4, 9.4 }] = 1890;


     std::map<std::string, CityRecord> cityMap; //std::unoreded_map<std::string,CityRecord> cityMap;
     std::map<CityRecord,uint32_t> cityFounded;
     //cityFounded[CityRecord { "beijing", 5000000, 2.4, 9.4 }] = 1982;

     cityMap["beijing"] = CityRecord { "beijing", 20000000, 2.4, 9.4 };
     cityMap["shanghai"] = CityRecord { "shanghai", 17000000, 2.4, 9.4 };
     cityMap["heze"] = CityRecord { "heze", 9000000, 2.4, 9.4 };
     cityMap["jinan"] = CityRecord { "jinan", 12000000, 2.4, 9.4 };
     cityMap["xian"] = CityRecord { "xian", 11000000, 2.4, 9.4 };

    //  CityRecord &hezedata = cityMap["heze"];
    //  std::cout << hezedata.Population << std::endl;

     const auto& cities = cityMap;
     if(cities.find("heze") != cities.end() )
     {
        std::cout << "find heze data" << std::endl;
        const CityRecord& belinData = cities.at("heze"); //at() 寻找的index不存在，则crash
        std::cout << belinData.Population << std::endl; 
     }

    // for(auto& [name, city] : cities) //c++17
    // {
    //     std::cout << name << "\n Population:  " << city.Population << std::endl;
    // }

    for(auto& kv : cityMap)
    {
        std:: cout << kv.first << "\n Population: " << kv.second.Population << std::endl; 
        cityFounded[kv.second];
    }

     for(auto& kv : cityFounded)
     {
        std::cout << kv.first.Name << " " << kv.first.Population << std::endl;
     }
}